unit database_armours;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
  Buttons, Spin, Menus, database_base, itemselectorframeunit,
  paramchangesframeunit, traitlist, fpjson;

type

  { TDatabaseArmoursFrame }

  TDatabaseArmoursFrame = class(TDatabaseBaseFrame)
    AdditionalDataPanel: TPanel;
    CopyMenuItem: TMenuItem;
    CutMenuItem: TMenuItem;
    DeleteMenuItem: TMenuItem;
    EditMenuItem: TMenuItem;
    EquipTypeComboBox: TComboBox;
    AnimationLabel: TLabel;
    AnimationPanel: TPanel;
    ArmourSelectorFrame: TItemSelectorFrame;
    DescriptionLabel: TLabel;
    DescriptionMemo: TMemo;
    DescriptionPanel: TPanel;
    GeneralSettingsFlowPanel: TFlowPanel;
    GeneralSettingsGroupBox: TGroupBox;
    IconIdLabel: TLabel;
    IconLabel: TLabel;
    IconPanel: TPanel;
    IconSpeedButton: TSpeedButton;
    MainContentScrollBox: TScrollBox;
    NameEdit: TEdit;
    NameLabel: TLabel;
    NamePanel: TPanel;
    NotesGroupBox: TGroupBox;
    NotesMemo: TMemo;
    ParamChangesFlowPanel: TFlowPanel;
    ParameterChangesGroupBox: TGroupBox;
    PasteMenuItem: TMenuItem;
    PriceLabel: TLabel;
    PricePanel: TPanel;
    PriceSpinEdit: TSpinEdit;
    SelectorContentSplitter: TSplitter;
    MainAdditionalContentSplitter: TSplitter;
    TraitsGroupBox: TGroupBox;
    TraitsListBox: TListBox;
    TraitsNotesSplitter: TSplitter;
    TypeComboBox: TComboBox;
    TypeLabel: TLabel;
    TypePanel: TPanel;
    ArmourParamChangesFrame: TParamChangesFrame;
    ArmourTraitListFrame: TTraitListFrame;
    procedure AnimationPanelClick(Sender: TObject);
    procedure DescriptionMemoChange(Sender: TObject);
    procedure IconSpeedButtonClick(Sender: TObject);
    procedure Init; override;
    procedure NameEditChange(Sender: TObject);
    procedure NotesMemoChange(Sender: TObject);
    procedure PriceSpinEditChange(Sender: TObject);
    procedure TypeComboBoxChange(Sender: TObject);
  private
    IsLoading: Boolean;
    SelectedId: Integer;
    procedure ResizeMemo;
    procedure LoadGeneralSettings(Armour: TJSONObject);
    procedure LoadParamChanges(Armour: TJSONObject);
    procedure LoadAdditionalSettings(Armour: TJSONObject);
    procedure LoadIcon(Armour: TJSONObject);
    function GetSelectedArmour: TJSONObject;
  public
    procedure LoadArmourData(Id: Integer);
    procedure UpdateLanguage(Code: String); override;
  end;

resourcestring
  ArmoursHeader = 'Armours';

implementation

uses
  globals, gamefont, languagehelper, comboboxhelper, iconselection;

{$R *.lfm}

{ TDatabaseArmoursFrame }

procedure TDatabaseArmoursFrame.Init;
begin
  IsLoading := True;
  ArmourSelectorFrame.SetData(Db.Armours, @Db.ResizeArmours, @LoadArmourData);
  ArmourSelectorFrame.Title := ArmoursHeader;
  ArmourSelectorFrame.JsonDataType := 'application/rpgmv-armors';
  ArmourSelectorFrame.CreateElementCallback := @Db.CreateEmptyArmour;
  FillArmourTypeComboBox(TypeComboBox, Db);
  FillArmourEquipTypeComboBox(EquipTypeComboBox, Db);

  ArmourParamChangesFrame.SetDatabase(Db);
  ArmourParamChangesFrame.AutoSize := True;
  ArmourTraitListFrame.SetDatabase(Db);

  ResizeMemo;

  LoadArmourData(1);
end;

procedure TDatabaseArmoursFrame.DescriptionMemoChange(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if not IsLoading then
    Armour := GetSelectedArmour;

  if Armour <> nil then
    Armour.Strings['description'] := DescriptionMemo.Text;
end;

procedure TDatabaseArmoursFrame.IconSpeedButtonClick(Sender: TObject);
var
  Armour: TJSONObject = nil;
  IconIndex: Integer = 0;
  IconIndexJson: TJSONNumber;
begin
  Armour := GetSelectedArmour;
  if (Armour <> nil) and Armour.Find('iconIndex', IconIndexJson) then
    IconIndex := IconIndexJson.AsInteger;

  if IconSelectionForm.ShowIconSelection(IconIndex) then begin
    Armour.Integers['iconIndex'] := IconSelectionForm.SelectedIconId;
    LoadIcon(Armour);
  end;
end;

procedure TDatabaseArmoursFrame.AnimationPanelClick(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if not IsLoading then
    Armour := GetSelectedArmour;

  if Armour <> nil then
    Armour.Integers['etypeId'] := TypeComboBox.ItemIndex + 2;
end;

procedure TDatabaseArmoursFrame.NameEditChange(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if IsLoading then
    Exit;

  Armour := GetSelectedArmour;
  if Armour <> nil then begin
    Armour.Strings['name'] := NameEdit.Text;
    ArmourSelectorFrame.RefreshSelectedName;
  end;
end;

procedure TDatabaseArmoursFrame.NotesMemoChange(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if not IsLoading then
    Armour := GetSelectedArmour;

  if Armour <> nil then
    Armour.Strings['note'] := NotesMemo.Text;
end;

procedure TDatabaseArmoursFrame.PriceSpinEditChange(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if not IsLoading then
    Armour := GetSelectedArmour;

  if Armour <> nil then
    Armour.Integers['price'] := PriceSpinEdit.Value
end;

procedure TDatabaseArmoursFrame.TypeComboBoxChange(Sender: TObject);
var
  Armour: TJSONObject = nil;
begin
  if not IsLoading then
    Armour := GetSelectedArmour;

  if Armour <> nil then
    Armour.Integers['atypeId'] := TypeComboBox.ItemIndex + 1
end;

procedure TDatabaseArmoursFrame.ResizeMemo;
begin
  DescriptionMemo.Font.BeginUpdate;
  DescriptionMemo.Font.Name := GetMonospacedFontName;
  DescriptionMemo.Font.Size := GetMonospacedFontSize;
  DescriptionMemo.Font.EndUpdate;
  ResizeMemoForFont(DescriptionMemo, 55, 2)
end;

procedure TDatabaseArmoursFrame.LoadGeneralSettings(Armour: TJSONObject);
var
  ArmourName: String = '';
  Description: String = '';
  ArmourTypeId: Integer = 0;
  Price: Integer = 0;
  EquipmentTypeId: Integer = 0;
  NameJson, DescriptionJson: TJSONString;
  ArmourTypeIdJson, PriceJson, EquipmentTypeIdJson: TJSONNumber;
begin
  if (Armour <> nil) and Armour.Find('name', NameJson) then
    ArmourName := NameJson.AsString;
  NameEdit.Text := ArmourName;

  LoadIcon(Armour);

  if (Armour <> nil) and Armour.Find('description', DescriptionJson) then
    Description := DescriptionJson.AsString;
  DescriptionMemo.Text := Description;

  if (Armour <> nil) and Armour.Find('atypeId', ArmourTypeIdJson) then
    ArmourTypeId := ArmourTypeIdJson.AsInteger;
  TypeComboBox.ItemIndex := ArmourTypeId - 1;

  if (Armour <> nil) and Armour.Find('price', PriceJson) then
    Price := PriceJson.AsInteger;
  PriceSpinEdit.Value := Price;

  if (Armour <> nil) and Armour.Find('etypeId', EquipmentTypeIdJson) then
    EquipmentTypeId := EquipmentTypeIdJson.AsInteger;
  EquipTypeComboBox.ItemIndex := EquipmentTypeId - 2;
end;

procedure TDatabaseArmoursFrame.LoadParamChanges(Armour: TJSONObject);
var
  Params: TJSONArray;
begin
  if (Armour <> nil) and Armour.Find('params', Params) then
    ArmourParamChangesFrame.SetEditedParams(Params)
  else
    ArmourParamChangesFrame.SetEditedParams(nil);
end;

procedure TDatabaseArmoursFrame.LoadAdditionalSettings(Armour: TJSONObject);
var
  Notes: String = '';
  NotesJson: TJSONString;
  Traits: TJSONArray;
begin
  if (Armour <> nil) and Armour.Find('traits', Traits) then
    ArmourTraitListFrame.SetTraitList(Traits)
  else
    ArmourTraitListFrame.SetTraitList(nil);

  if (Armour <> nil) and Armour.Find('note', NotesJson) then
    Notes := NotesJson.AsString;
  NotesMemo.Text := Notes;
end;

procedure TDatabaseArmoursFrame.LoadIcon(Armour: TJSONObject);
var
  IconId: Integer = 0;
  IconIdJson: TJSONNumber;
  IconBitmap: TBitmap;
begin
  if (Armour <> nil) and Armour.Find('iconIndex', IconIdJson) then
    IconId := IconIdJson.AsInteger;

  IconIdLabel.Caption := IntToStr(IconId);
  if IconId <> 0 then begin
    IconBitmap := Game.GetIcon(IconId);
    IconSpeedButton.Glyph.Assign(IconBitmap);
    IconBitmap.Free;
  end else
    IconSpeedButton.Glyph.Clear;
end;

function TDatabaseArmoursFrame.GetSelectedArmour: TJSONObject;
begin
  GetSelectedArmour := nil;
  if Db.Weapons <> nil then
    if (SelectedId >= 1) and (SelectedId <= Db.Armours.Count -1) then
      GetSelectedArmour := Db.Armours.Objects[SelectedId];
end;

procedure TDatabaseArmoursFrame.LoadArmourData(Id: Integer);
var
  Armour: TJSONObject;
begin
  IsLoading := True;
  SelectedId := Id;

  Armour := GetSelectedArmour;
  LoadGeneralSettings(Armour);
  LoadParamChanges(Armour);
  LoadAdditionalSettings(Armour);

  IsLoading := False;
end;

procedure TDatabaseArmoursFrame.UpdateLanguage(Code: String);
begin
  inherited UpdateLanguage(Code);
  if IsLanguageRtl(Code) then begin
    GeneralSettingsFlowPanel.FlowStyle := fsRightLeftTopBottom;
  end else begin
    GeneralSettingsFlowPanel.FlowStyle := fsLeftRightTopBottom;
  end;
  ArmourParamChangesFrame.UpdateLanguage(Code);
end;

end.

